import { createSlice } from "@reduxjs/toolkit";
import { get } from "lodash-es";
import { getCookie, removeCookie, setCookie } from "@/utils/cookie";
import userApiService, { UserMenu } from "@/api/user";
import type { RootState } from "@/store";

export interface UserState {
  /* 用户 uid */
  uid: number | string | null;
  /**
   * 身份令牌
   */
  accessToken: string | null;
  /**
   * 名称
   */
  name: string | null;
  /**
   * 头像
   */
  avatar: string | null;
  /**
   * 权限
   */
  access: string | null;
  /**
   * 菜单
   */
  menus: UserMenu[];
  /**
   * 登陆状态
   */
  status: string | null;
  /**
   * 过期时间戳
   */
  expired: number;
}

const initialState: UserState = {
  accessToken: getCookie("accessToken") || null,
  name: null,
  uid: null,
  avatar: null,
  access: null,
  status: null,
  menus: [],
  expired: 0,
};

export const userSlice = createSlice({
  name: "userInfo",
  initialState: initialState,
  reducers: {
    logout: (state) => {
      removeCookie("accessToken");

      state.expired = 0;
      state.accessToken = null;
      state.uid = null;
      state.name = null;
      state.access = null;
      state.avatar = null;
    },
  },
  extraReducers: (builder) => {
    builder.addMatcher(
      userApiService.endpoints.login.matchFulfilled,
      (state, { payload }) => {
        if (payload.accessToken) setCookie("accessToken", payload.accessToken);

        state.accessToken = payload.accessToken;
        state.uid = payload.uid;
        state.name = payload.name;
        state.avatar = payload.avatar;
        state.access = payload.access;
      }
    );
    builder.addMatcher(
      userApiService.endpoints.getUserMenus.matchFulfilled,
      (state, { payload }) => {
        state.menus = payload.menus;
      }
    );
    builder.addMatcher(
      userApiService.endpoints.checkLogin.matchFulfilled,
      (state, { payload }) => {
        state.uid = payload.uid;
        state.name = payload.name;
        state.status = payload.status;
      }
    );
    builder.addMatcher(
      userApiService.endpoints.checkLogin.matchRejected,
      (state, { payload }) => {
        if (["401", "2008"].includes(get(payload, "errCode", ""))) {
          state.accessToken = null;
        }
      }
    );
  },
});

export const selectUserInfo = (state: RootState): UserState => state.userInfo;
export const selectUserMenus = (state: RootState) => state.userInfo.menus;
export const { logout } = userSlice.actions;
export default userSlice.reducer;
